package org.ezaero.jmimic.impl.store.xstream;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;

import org.ezaero.jmimic.api.StoreFormat;
import org.jmock.api.Invocation;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.binary.BinaryStreamReader;
import com.thoughtworks.xstream.io.binary.BinaryStreamWriter;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
import com.thoughtworks.xstream.io.xml.XppDriver;

public class XStreamFactory {

	public static XStream create(StoreFormat format) {
		switch (format) {
		case BIN:
			return createBinary();
//		case JSON:
//			return createJson();
		case XML:
			return createXml();
		}
		throw new IllegalStateException("Unsupported format:" + format);
	}

	public static XStream createJson() {
		final JettisonMappedXmlDriver driver = new JettisonMappedXmlDriver();
		final XStream xstream = init(driver);
		xstream.setMode(XStream.NO_REFERENCES);
		return xstream;
	}

	public static XStream createXml() {
		return init(new XppDriver());
	}

	public static XStream createBinary() {
		final HierarchicalStreamDriver driver = new HierarchicalStreamDriver() {
			public HierarchicalStreamWriter createWriter(OutputStream arg0) {
				return new BinaryStreamWriter(arg0);
			}

			public HierarchicalStreamReader createReader(InputStream arg0) {
				return new BinaryStreamReader(arg0);
			}

			public HierarchicalStreamReader createReader(Reader arg0) {
				return null;
			}

			public HierarchicalStreamWriter createWriter(Writer arg0) {
				return null;
			}

		};
        final XStream xstream = init(driver);
		return xstream;
	}

    private static XStream init(final HierarchicalStreamDriver driver) {
        final XStream xstream = new XStream(driver);
        xstream.alias("MMCINV", Invocation.class);
        return xstream;
    }

}
